﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PdfLibrary
{
    public class PdfGraphicsReader
    {
        public List<IPdfObject> Objects = new List<IPdfObject>();

        public PdfGraphicsReader(byte[] content)
        {
            var reader = new PdfReader(content, null);

            while (!reader.EndOfFile)
            {
                var x = PdfObject.CreateFromReader(reader, true);
                Objects.Add(x);
                reader.SkipWhitespaceCharacters();
            }
        }
    }

    public class PdfGraphicsCommands
    {
        public static Dictionary<string, Type> CommandFactory = new Dictionary<string, Type>()
        {
            { "CS", typeof(PdfCommandSetStrokingColourSpace) },
            { "cs", typeof(PdfCommandSetNonStrokingColourSpace) },
            { "BT", typeof(PdfCommandBeginText) },
            { "ET", typeof(PdfCommandEndText) },
            { "SCN", typeof(PdfCommandSetStrokingColour) },
            { "scn", typeof(PdfCommandSetNonStrokingColour) },
            { "Tf", typeof(PdfCommandSetFontSize) },
            { "i", typeof(PdfCommandSetFlatnessTolarence) },
            { "Td", typeof(PdfCommandSetNextLineStart) },
            { "TD", typeof(PdfCommandSetNextLineStartAndLeading) },
            { "T*", typeof(PdfCommandSetNextLineStartWithLeading) },
            { "TJ", typeof(PdfCommandShowTextArray) },
            { "Tj", typeof(PdfCommandShowText) },
            { "Do", typeof(PdfCommandPaintXObject) },

            { "q", typeof(PdfCommandSaveGraphicsState) },
            { "Q", typeof(PdfCommandRestoreGraphicsState) },
            { "cm", typeof(PdfCommandCTMConcatenate) },
            { "Tm", typeof(PdfCommandSetTextMatrix) },
            { "re", typeof(PdfCommandUnknown) },
            { "W", typeof(PdfCommandUnknown) },
            { "n", typeof(PdfCommandUnknown) },
            { "f", typeof(PdfCommandUnknown) },
            { "Tc", typeof(PdfCommandUnknown) },
            { "ri", typeof(PdfCommandUnknown) },
        };

        public List<IPdfCommand> Commands = new List<IPdfCommand>();

        public PdfGraphicsCommands(PdfGraphicsReader reader)
        {
            var parameterStack = new List<IPdfObject>();
            foreach (var item in reader.Objects)
            {
                if (item is PdfCommand)
                {
                    var codeName = ((PdfCommand) item).Name;

                    Type commandType;
                    if (!CommandFactory.TryGetValue(codeName, out commandType))
                        commandType = typeof(PdfCommandUnknown);

                    var command = (IPdfCommand)Activator.CreateInstance(commandType, parameterStack.ToArray());

                    if (command is PdfCommandUnknown)
                        ((PdfCommandUnknown) command).Code = codeName;

                    this.Commands.Add(command);

                    parameterStack.Clear();
                }
                else
                {
                    parameterStack.Add(item);
                }
            }
        }
    }
}
